{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 马尔可夫预测\n",
    "**本节只讨论时齐的马尔可夫链**\n",
    "\n",
    "- 马尔可夫链: $\\{\\xi_n,\\ n=1,2,\\cdots\\}$\n",
    "- 马尔可夫链性质: $P\\{\\xi_{n+m}|\\xi_n=i,\\xi_{n-1}=i_{n-1},\\cdots,\\xi_{1}=i_1\\}=P\\{\\xi_{n+m}|\\xi_n=i\\}$\n",
    "- 时齐的马尔可夫链还要满足:$P\\{\\xi_{n+m}|\\xi_n=i\\}=p_{ij}(m)$. 即上式右边与n无关. 其含义是, 系统从i到j经过m个时间间隔, 这与起始时刻无关.\n",
    "- 马尔可夫链的$m$步转移矩阵: $P(m)=(p_{ij}(m))$. $m=1$时简称为转移矩阵.\n",
    "- 柯尔莫哥洛夫-开普曼定理: 对 Markov Train 有: $p_{ij}(n+m)=\\sum\\limits_{k\\in E}p_{ik}(n)p_{kj}(m)$\n",
    "- 第$n$步概率分布为: $P^{(n)}=P^{(0)}P^n$\n",
    "- 正则转移矩阵: 当且仅当存在正整数$k$, 使$P^k$的每一元素都是正数.\n",
    "    - 正则转移矩阵具有唯一的不动向量.\n",
    "    - 对于正则转移矩阵, $\\lim\\limits_{n\\rightarrow\\infty}P^{n}$每一行都趋于不动向量(遍历性)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "得到概率估计的转移矩阵:\n",
      "[[0.4        0.4        0.1        0.1       ]\n",
      " [0.27272727 0.18181818 0.36363636 0.18181818]\n",
      " [0.36363636 0.36363636 0.18181818 0.09090909]\n",
      " [0.         0.14285714 0.57142857 0.28571429]]\n",
      "这是一个正则转移矩阵, 它的10次幂为:\n",
      "[[0.29393371 0.28893058 0.26829268 0.14884303]\n",
      " [0.29393371 0.28893058 0.26829268 0.14884303]\n",
      " [0.29393371 0.28893058 0.26829268 0.14884303]\n",
      " [0.29393371 0.28893058 0.26829268 0.14884303]]\n"
     ]
    }
   ],
   "source": [
    "# 例15.9\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "state_num = 4\n",
    "states = [4, 3, 2, 1, 4, 3, 1, 1, 2, 3,\n",
    "          2, 1, 2, 3, 4, 4, 3, 3, 1, 1,\n",
    "          1, 3, 3, 2, 1, 2, 2, 2, 4, 4,\n",
    "          2, 3, 2, 3, 1, 1, 2, 4, 3, 1\n",
    "         ]\n",
    "P = np.zeros((state_num, state_num), dtype=np.int)\n",
    "for i in range(len(states)-1):\n",
    "    P[states[i]-1][states[i+1]-1] += 1\n",
    "\n",
    "P = np.divide(P, np.sum(P, axis=1)[:,None])\n",
    "print('得到概率估计的转移矩阵:', P, sep='\\n')\n",
    "\n",
    "print('这是一个正则转移矩阵, 它的10次幂为:',np.matrix(P)**10, sep='\\n')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.71428571 0.13095238 0.1547619 ]\n",
      " [0.71428571 0.13095238 0.1547619 ]\n",
      " [0.71428571 0.13095238 0.1547619 ]]\n",
      "[[0.71428571 0.13095238 0.1547619 ]]\n"
     ]
    }
   ],
   "source": [
    "# 例15.11\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "P = np.matrix([[0.8, 0.1, 0.1],\n",
    "               [0.5, 0.1, 0.4],\n",
    "               [0.5, 0.3, 0.2]\n",
    "              ])\n",
    "\n",
    "p = np.matrix([0.2, 0.4, 0.4])\n",
    "\n",
    "print(P**20)\n",
    "print(p*P**20)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
